.TH std::atomic_flag_test_and_set,std::atomic_flag_test_and_set_explicit 3 "2024.06.10" "http://cppreference.com" "C++ Standard Libary"
.SH NAME
std::atomic_flag_test_and_set,std::atomic_flag_test_and_set_explicit \- std::atomic_flag_test_and_set,std::atomic_flag_test_and_set_explicit

.SH Synopsis
   Defined in header <atomic>
   bool atomic_flag_test_and_set( volatile std::atomic_flag* obj )    \fB(1)\fP \fI(since C++11)\fP
   noexcept;
   bool atomic_flag_test_and_set( std::atomic_flag* obj ) noexcept;   \fB(2)\fP \fI(since C++11)\fP
   bool atomic_flag_test_and_set_explicit( volatile std::atomic_flag*
   obj,                                                               \fB(3)\fP \fI(since C++11)\fP
                                           std::memory_order order )
   noexcept;
   bool atomic_flag_test_and_set_explicit( std::atomic_flag* obj,
                                           std::memory_order order )  \fB(4)\fP \fI(since C++11)\fP
   noexcept;

   Atomically changes the state of a std::atomic_flag pointed to by obj to set (true)
   and returns the value it held before.

   1,2) The memory synchronization order is std::memory_order_seq_cst.
   3,4) The memory synchronization order is order.

.SH Parameters

   obj   - pointer to std::atomic_flag to access
   order - the memory synchronization order

.SH Return value

   The value previously held by the flag pointed to by obj.

.SH Notes

   std::atomic_flag_test_and_set and std::atomic_flag_test_and_set_explicit can be
   implemented as obj->test_and_set() and obj->test_and_set(order) respectively.

.SH Example

   A spinlock mutex can be implemented in userspace using an std::atomic_flag.


// Run this code

 #include <atomic>
 #include <iostream>
 #include <thread>
 #include <vector>

 std::atomic_flag lock = ATOMIC_FLAG_INIT;

 void f(int n)
 {
     for (int cnt = 0; cnt < 100; ++cnt)
     {
         while (std::atomic_flag_test_and_set_explicit(&lock, std::memory_order_acquire))
             ; // spin until the lock is acquired
         std::cout << "Output from thread " << n << '\\n';
         std::atomic_flag_clear_explicit(&lock, std::memory_order_release);
     }
 }

 int main()
 {
     std::vector<std::thread> v;
     for (int n = 0; n < 10; ++n)
         v.emplace_back(f, n);
     for (auto& t : v)
         t.join();
 }

.SH Output:

 Output from thread 2
 Output from thread 6
 Output from thread 7
 ...<exactly 1000 lines>...

.SH See also

   atomic_flag                the lock-free boolean atomic type
   \fI(C++11)\fP                    \fI(class)\fP
   atomic_flag_clear
   atomic_flag_clear_explicit atomically sets the value of the flag to false
   \fI(C++11)\fP                    \fI(function)\fP
   \fI(C++11)\fP
   memory_order               defines memory ordering constraints for the given atomic
   \fI(C++11)\fP                    operation
                              \fI(enum)\fP
   C documentation for
   atomic_flag_test_and_set,
   atomic_flag_test_and_set_explicit
